package com.itsm.example.audit.service.impl;

import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.itsm.example.audit.mapper.AuditMapper;
import com.itsm.example.audit.pojo.context.AuditContext;
import com.itsm.example.audit.pojo.domain.AuditDO;
import com.itsm.example.audit.pojo.enums.StateMachineEnum;
import com.itsm.example.audit.pojo.event.AuditEvent;
import com.itsm.example.audit.pojo.state.AuditState;
import com.itsm.example.audit.service.AuditService;
import com.itsm.example.statemachine.bo.ItsmEvent;
import com.itsm.example.statemachine.factory.StateMachineEngine;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.List;

/**
 * @author benym
 * @date 2023/7/12 15:56
 */
@Service
@Slf4j
public class AuditServiceImpl extends ServiceImpl<AuditMapper, AuditDO> implements AuditService {

    @Autowired
    private StateMachineEngine stateMachineEngine;

    @Override
    public AuditDO audit(AuditContext auditContext) {
        auditContext = prepareParameter(auditContext);
        AuditState nowState = AuditState.getState(auditContext.getStateValue());
        AuditEvent nowEvent = AuditEvent.getEvent(auditContext.getEventId());
        // 执行状态机
        stateMachineEngine.fire(nowState, nowEvent, auditContext);
        //从当前上下文中获取最新实体类数据
        return auditContext.getAuditDO();
    }

    @Override
    public List<ItsmEvent> getNextStep(AuditContext auditContext) {
        auditContext = prepareParameter(auditContext);
        return stateMachineEngine.getNextEvents( AuditState.getState(auditContext.getStateValue()), auditContext);
    }

    @Override
    public String uml(AuditContext auditContext) {
        auditContext = prepareParameter(auditContext);
        return stateMachineEngine.generateUml(auditContext);
    }

    /**
     * 根据工单id获取上下文信息
     * @param auditContext
     * @return
     */
    private AuditContext prepareParameter(AuditContext auditContext) {
        AuditDO auditDO = getById(auditContext.getId());
        if (auditDO == null) {
            //初始化实例id和状态
            auditContext.setInstId(StateMachineEnum.TEST_MACHINE.getCode());
            auditContext.setStateValue(AuditState.APPLY.getValue());
//            return AuditDO.builder().id(auditContext.getId()).auditState(AuditState.APPLY.getValue()).build();
        }else {
            auditContext.setInstId(auditDO.getInstId());
            auditContext.setStateValue(auditDO.getAuditState());
        }
        return auditContext;
    }
}
